#include "vector.h"

// 创建
vector vector_create(int initial_cap)
{
    vector v = (vector)malloc(sizeof(struct _vector));

    if (NULL == v)
    {
        fprintf(stderr, "create:: malloc error!\n");
        return NULL;
    }

    v->size = 0;
    v->cap = initial_cap; // 容量
    v->buff = (elem_type *)malloc(sizeof(elem_type) * v->cap);

    if (NULL == v->buff)
    {
        fprintf(stderr, "malloc error\n");
        return NULL;
    }

    return v;
}

// 清空某个顺序表
void vector_clear(vector v)
{
    v->size = 0;
}

// 销毁某个顺序表
void vector_destroy(vector v)
{
    free(v->buff);
    free(v);
}

// 向顺序表中插入一个新节点

// 扩容
void vector_expand_storage(vector v)
{
    // 如果容量不足就进行扩容操作
    if (v->cap == v->size)
    {
        elem_type *p = (elem_type *)realloc(v->buff, (v->cap + 10) * sizeof(elem_type));


        if (p == NULL)
        {
            fprintf(stderr, "vector_expand_storage:: realloc error\n");
            return;
        }

        v->buff = p;
        v->cap += 100;
    }
}

// 缩容
void vector_reduce_storage(vector v, unsigned int cap)
{
    // 如果空闲容量较多就进行缩容操作
    if (v->cap - v->size >= cap)
    {
        elem_type *p = (elem_type *)realloc(v->buff, (v->cap - cap) * sizeof(elem_type));

        if (p == NULL)
        {
            fprintf(stderr, "realloc error\n");
            return;
        }

        v->buff = p;
        v->cap -= 100;
    }
}

// 尾插
void vector_push_back(vector v, elem_type data)
{
    // 时间复杂度为 O(1)

    // 如果容量不足就进行扩容操作
    vector_expand_storage(v);

    v->buff[v->size] = data;
    v->size++;
}

// 头插
void vector_push_front(vector v, elem_type data)
{
    // 时间复杂度为 O(n)

    int i;

    // 如果容量不足就进行扩容操作
    vector_expand_storage(v);

    for (i = v->size; i > 0; i--)
    {
        v->buff[i] = v->buff[i - 1];
    }

    v->buff[0] = data;
    v->size++;
}

// 中插
void vector_insert(vector v, unsigned int pos, elem_type data)
{
    int i;

    // 如果容量不足就进行扩容操作
    vector_expand_storage(v);

    if (pos > v->size) // 判尾部中插
        pos = v->size;

    for (i = v->size; i > pos; i--)
    {
        v->buff[i] = v->buff[i - 1];
    }

    v->buff[pos] = data;
    v->size++;
}
